package com.cictec.middleware.tde.rm;

import java.beans.PropertyEditor;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.core.filterchain.IoFilter;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.executor.ExecutorFilter;
import org.apache.mina.filter.executor.OrderedThreadPoolExecutor;
import org.apache.mina.filter.logging.MdcInjectionFilter;
import org.apache.mina.integration.beans.InetSocketAddressEditor;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.CustomEditorConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.cictec.middleware.tde.rm.mina.filter.AuthenticationFilter;
import com.cictec.middleware.tde.rm.mina.filter.AutoResponseFilter;
import com.cictec.middleware.tde.rm.mina.filter.LogFilter;
import com.cictec.middleware.tde.rm.mina.filter.SendMonitorFilter;
import com.cictec.middleware.tde.rm.mina.handler.TerminalMessageHandler;
import com.cictec.middleware.tde.rm.protocol.TerminalProtocolCodecFactory;

/**
 * 锐明协议mina服务配置
 * @author Administrator
 *
 */
@Configuration
public class RmMinaConfiguration {

	
	private static Map<Class<?>, Class<? extends PropertyEditor>> customEditors = new HashMap<>();
	@Bean
	public static CustomEditorConfigurer customEditorConfigurer() {
		customEditors.put(SocketAddress.class, InetSocketAddressEditor.class);
		CustomEditorConfigurer customEditorConfigurer = new CustomEditorConfigurer();
		customEditorConfigurer.setCustomEditors(customEditors);
		return customEditorConfigurer;
	}
	
	/**
	 * 监听端口号
	 */
	private int port;

	// 已在 MinaCustomEditorConfiguration 统一实现
//	private Map<Class<?>, Class<? extends PropertyEditor>> customEditors = new HashMap<>();
//	@Bean
//	public CustomEditorConfigurer customEditorConfigurer() {
//		customEditors.put(SocketAddress.class, InetSocketAddressEditor.class);
//		CustomEditorConfigurer customEditorConfigurer = new CustomEditorConfigurer();
//		customEditorConfigurer.setCustomEditors(customEditors);
//		return customEditorConfigurer;
//	}

	/* ********** mina过滤器 start*********************************** */
	
	@Autowired
	public LogFilter logFilter;
	@Autowired
	public AuthenticationFilter authenticationFilter;
	@Autowired
	public AutoResponseFilter autoResponseFilter;
	@Autowired
	public SendMonitorFilter sendMonitorFilter;
	@Autowired
	public TerminalProtocolCodecFactory terminalProtocolCodecFactory;
	 
	/**
	 * 编解码工厂
	 * @return
	 */
	@Bean
	public ProtocolCodecFilter protocolCodecFilter() {
		ProtocolCodecFilter filter = new ProtocolCodecFilter(terminalProtocolCodecFactory);
		return filter;
	}
	
	@Bean
	public ExecutorFilter executorFilter() {
		// return new ExecutorFilter();
		ExecutorFilter filter = new ExecutorFilter(orderedThreadPoolExecutor());
		return filter;
	}
	/* ********** mina过滤器 end *********************************** */
	
	/* ********** 连接池 start ***************************************/
	
	@Bean
	public OrderedThreadPoolExecutor orderedThreadPoolExecutor() {
		OrderedThreadPoolExecutor pool = new OrderedThreadPoolExecutor(10, 30);
		return pool;
	}
	/* ********** 连接池 end ***************************************/

	
	@Bean
	public DefaultIoFilterChainBuilder defaultIoFilterChainBuilder() {
		DefaultIoFilterChainBuilder defaultIoFilterChainBuilder = new DefaultIoFilterChainBuilder();

		Map<String, IoFilter> filters = new LinkedHashMap<>();
		filters.put("excuterFilter", executorFilter());
		filters.put("logFilter", logFilter);
		filters.put("codecFilter", protocolCodecFilter());
		filters.put("authenticationFilter", authenticationFilter);
		filters.put("autoResponseFilter", autoResponseFilter);
		filters.put("sendMonitorFilter", sendMonitorFilter);
		defaultIoFilterChainBuilder.setFilters(filters);
		return defaultIoFilterChainBuilder;
	}
	
	@Autowired
	public TerminalMessageHandler terminalMessageHandler;

//	@Bean(initMethod = "bind", destroyMethod = "unbind", name="rmIoAcceptor")
	@Bean(name="rmIoAcceptor")
	public NioSocketAcceptor nioSocketAcceptor() {

		NioSocketAcceptor nioSocketAcceptor = new NioSocketAcceptor();
		nioSocketAcceptor.setDefaultLocalAddress(new InetSocketAddress(port));
		nioSocketAcceptor.setReuseAddress(true);
		nioSocketAcceptor.setFilterChainBuilder(defaultIoFilterChainBuilder());
		nioSocketAcceptor.setHandler(terminalMessageHandler);
		return nioSocketAcceptor;
	}

	
	@Bean
	public MdcInjectionFilter mdcInjectionFilter() {
		return new MdcInjectionFilter(MdcInjectionFilter.MdcKey.remoteAddress);
	}

	public int getPort() {
		return port;
	}

	public void setPort(int port) {
		this.port = port;
	}
}
